﻿using System;
using System.Data;
using System.Collections.Specialized;
using System.Data.SqlClient;
using FileMonitor.Configuration.Prototype;
using FileMonitor.Configuration.Prototype.BizProcess;
using MonitorProvider.Prototype.FileReader;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using FileUtility.ExceptionExt;
namespace MonitorProvider.Prototype
{
    internal class SaveDBProcess : IProcessFile, IDisposable
    {
        #region Private Members
       // private DDNP.Supports.Common.DDNPSqlDatabase targetExchangDB;
   
        private string _dataFilter;
        //private string _splitChar;
        //private string _splitArr;
    
        private string _fileReaderProviderType = "Default";
        int _fileType = 0;
    

        #endregion

        #region Public Properties
        //public string DataFilter
        //{
        //    get
        //    {
        //        return this._dataFilter;
        //    }
        //    set
        //    {
        //        this._dataFilter = value;
        //    }
        //}
        //public string SplitChar
        //{
        //    get 
        //    {
        //        return this._splitChar;
        //    }
        //    set
        //    {
        //        this._splitChar = value;
        //    }
        //}
        #endregion

        #region Constructor
        public SaveDBProcess()
        {
         //   base. = ProcessType.ExChangeDB;
        }
        #endregion


        private FileReaderBase GetFileReader(FileProcessConfiguration fileProcessConfig)
        {
            FileReaderBase fileReader;
            FileReader.FileType filetype = FileReader.FileType.TXT;

            if (!string.IsNullOrEmpty(fileProcessConfig.FileType))
            {
                filetype = (FileReader.FileType)Enum.Parse(typeof(FileReader.FileType), fileProcessConfig.FileType, true);
            }
            fileReader = FileReader.FileReaderFactory.Create(filetype, this._fileReaderProviderType);
            fileReader.Initialize(filetype, fileProcessConfig);
            return fileReader;
        }
       
        #region IProcessFile Members

        public ExcutedTask ProcessFile(PlantProcessConfiguration plantProcessConfig, FileProcessConfiguration fileProcessConfig, string PlantCode, string FileName, string filePath)
        {

            SqlDatabase targetExchangDB;
            if (plantProcessConfig == null)
            {
                targetExchangDB = FileMonitor.Configuration.Providers.ProviderService.GetProvider().GetAllDataBase()[fileProcessConfig.TargetDatabaseName];
            }
            else
            {
                targetExchangDB = new Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase(plantProcessConfig.DBConnstring);
            }
            FileReaderBase fileReader = this.GetFileReader(fileProcessConfig);

            string _Prifix;
            int totalFiles, currentFile;
            InitializeFileInfo(FileName, out _Prifix, out totalFiles, out currentFile);


            #region  Get BatchId and Check is new batch,if new batch,add file log

            bool IsNew = true;
            Guid batchId = FileUtility.DBUtility.GetBatchID(fileProcessConfig.DataType, targetExchangDB, "TransferLogT", _Prifix, out IsNew);
            if (IsNew)
            {
                currentFile = 0;
                FileUtility.DBUtility.AddNewFileLog(targetExchangDB, batchId, fileProcessConfig.DataType, fileProcessConfig.MonitorPath, _Prifix, totalFiles, currentFile, 0, -1, PlantCode);
            }
            #endregion

            bool isLastFile = false;
            try
            {
                Save(fileProcessConfig, targetExchangDB, filePath, fileReader, batchId, out isLastFile);
            }
            catch (DataException ex)
            {
                throw new DBSaveException(ex.Message,ex); 
            }
            catch (SqlException ex)
            {
                throw new DBSaveException(ex.Message, ex);
            }
            catch (FileUtility.ExceptionExt.FileContentRedaerException ex)
            {
                throw ex;
            }

            ExcutedTask task = new ExcutedTask()
            {
                Owner = PlantCode,
                BatchId = batchId.ToString(),
                FileName = FileName,
                IsLastFile = isLastFile,
                IsNewBacth = IsNew
            };
            return task;
        }
         #endregion

        #region Private Methods
        private void InitializeFileInfo(string fileName, out string prifix, out int totalFiles, out int currentFile)
        {
            #region Init Prfix,totalFiles,currentFile
            string _fileCountsExt;
            if (fileName.IndexOf("(") > 0)
            {
                prifix = fileName.Substring(0, fileName.LastIndexOf("("));
                _fileCountsExt = fileName.Substring(fileName.LastIndexOf("(") + 1, fileName.LastIndexOf(")") - fileName.LastIndexOf("(") - 1);
                totalFiles = Int32.Parse(_fileCountsExt.Substring(0, _fileCountsExt.IndexOf("_")));
                currentFile = Int32.Parse((_fileCountsExt.Substring(_fileCountsExt.IndexOf("_"), _fileCountsExt.Length - _fileCountsExt.IndexOf("_"))).TrimStart("_".ToCharArray()));
            }
            else
            {
                prifix = fileName.Substring(0, fileName.LastIndexOf("."));
                totalFiles = 1;
                currentFile = 1;
            }
            #endregion
        }

        private void Save(FileProcessConfiguration fileProcessConfig, SqlDatabase targetExchangDB, string filePath,FileReaderBase fileReader,Guid batchId,out bool isLastFile) 
        {
            object objContent;
             isLastFile = false;
            try
            {
                DataTable _dtScheml = FileUtility.DBUtility.GetDataTableNoData(targetExchangDB, fileProcessConfig.TargetTable);
                objContent = fileReader.GetFileProcessedResult(filePath, _dtScheml, batchId);
            }
            catch (Exception ex)
            {
                throw ex;
             //   throw new Exception(ex.GetType().FullName + " Exception Occured at Reading file content to DataTable:" + ex.Message);
            }
            try
            {
                if (objContent is DataTable)
                {
                    DataTable dtContent = objContent as DataTable;
                    SaveData(dtContent, targetExchangDB, fileProcessConfig.TargetTable, batchId, fileProcessConfig.DataFilter);
                }
                else if (objContent is DataSet)
                {
                    foreach (DataTable dt in (objContent as DataSet).Tables)
                    {
                        SaveData(dt, targetExchangDB, fileProcessConfig.TargetTable, batchId, fileProcessConfig.DataFilter);
                    }
                }
                isLastFile = FileUtility.DBUtility.CheckIsLastFile(targetExchangDB, batchId);
            }
            catch (Exception ex)
            {
                throw ex;
                //throw new Exception(ex.GetType().FullName + " Expcetion Occured at Saving to Database:" + ex.Message);
            }
        }

        private void SaveData(DataTable dtContent,SqlDatabase targetExchangDB, string targetTable, Guid batchId,string dataFilter)
        {
            try
            {
                string _connString = targetExchangDB.CreateConnection().ConnectionString;
                System.Data.SqlClient.SqlBulkCopy sqlBulkCopy = new System.Data.SqlClient.SqlBulkCopy(_connString, System.Data.SqlClient.SqlBulkCopyOptions.UseInternalTransaction);
                sqlBulkCopy.DestinationTableName = targetTable;
                sqlBulkCopy.BulkCopyTimeout = 360;
                if (!string.IsNullOrEmpty(dataFilter))
                {
                    DataRow[] rows = dtContent.Select(dataFilter);
                    sqlBulkCopy.WriteToServer(rows);
                    FileUtility.DBUtility.AddFileCount(targetExchangDB, batchId, rows.Length);
                }
                else
                {
                    sqlBulkCopy.WriteToServer(dtContent);
                    FileUtility.DBUtility.AddFileCount(targetExchangDB, batchId, dtContent.Rows.Count);
                }
            }
            catch (DataException dataException)
            {
                throw dataException;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region IDisposeable Member
        public void Dispose()
        {
            //this.isInitialize = false;
           // this.targetExchangDB = null;
        }
        #endregion

    }
}
